package org.finesys.common.disruptor.event.handler.chain;

import lombok.extern.slf4j.Slf4j;
import org.finesys.common.disruptor.event.DisruptorEvent;
import org.finesys.common.disruptor.event.handler.DisruptorHandler;
import org.finesys.common.disruptor.event.handler.chain.def.DefaultNamedHandlerList;
import org.springframework.util.ObjectUtils;

import java.util.List;

@Slf4j
public class ProxiedHandlerChain implements HandlerChain<DisruptorEvent> {

    private ProxiedHandlerChain originalChain;
    private List<DisruptorHandler<DisruptorEvent>> handlerList;
    private int currentPosition = 0;

    public ProxiedHandlerChain() {
        this.currentPosition = -1;
    }

    public ProxiedHandlerChain(ProxiedHandlerChain handlerChain, DefaultNamedHandlerList disruptorHandlers) {
        if (handlerChain == null) {
            throw new NullPointerException("original HandlerChain cannot be null.");
        }
        this.originalChain = handlerChain;
        this.handlerList = disruptorHandlers;
        this.currentPosition = 0;
    }

    @Override
    public void doHandler(DisruptorEvent event) throws Exception {
        if (ObjectUtils.isEmpty(handlerList) || handlerList.size() == this.currentPosition) {
            if (log.isTraceEnabled()) {
                log.trace("Invoking original filter chain.");
            }
            if (this.originalChain != null) {
                this.originalChain.doHandler(event);
            }
        } else {
            if (log.isTraceEnabled()) {
                log.trace("Invoking wrapped filter at index [" + this.currentPosition + "]");
            }
            this.handlerList.get(this.currentPosition++).doHandler(event, this);
        }

    }
}
